#include"driver.h"
#include"def.h"
#ifdef CHAPTER4
#include"symtable.h"
#endif
#ifdef CHAPTER5
#include"symtable.h"
#include"semantic.h"
#endif
#ifdef CHAPTER7
#include"symtable.h"
#include"semantic.h"
#include"IR.h"
#endif
using namespace std;
extern node* root;
driver* getDriver(node* drive){
#ifdef CHAPTER7
  return new IRDriver(new symDriver(new semanticDriver(new nodeDriver(drive))));
#endif
#ifdef CHAPTER5
  return new symDriver(new semanticDriver(new nodeDriver(drive)));
#endif
#ifdef CHAPTER4
  return new symDriver(new nodeDriver(drive));
#endif
  return new nodeDriver(drive);
}

driver::driver(){

}

driver::driver(driver* myDriver):myDriver(myDriver){
  
}

node* driver::getNode(){
  if(myDriver){
    return myDriver->getNode();
  }
  return NULL;
}

void driver::addcal(initializer_list<analyzer> li){
  for(analyzer f:li)
    cal.push_back(f);
}

void driver::addop(initializer_list<analyzer> li){
  for(analyzer f:li)
    op.push_back(f);
}

void driver::addexit(initializer_list<analyzer> li){
  for(analyzer f:li)
    end.push_back(f);
}

int driver::calculate(){
  if(myDriver){
    if(myDriver->calculate()<0)return -1;
  }
  for(analyzer f:cal){
    if(f(this)<0)return -1;
  }
  return 1;
}

int driver::exec(){
  if(myDriver){
    if(myDriver->exec()<0)return -1;
  }
  for(analyzer f:op){
    if(f(this)<0)return -1;
  }
  return 1;
}

int driver::exit(){
  if(myDriver){
    if(myDriver->exit()<0)return -1;
  }
  for(analyzer f:end){
    if(f(this)<0)return -1;
  }
  return 1;
}

void analyze(node* tree){
  tree->myDriver->exec();
  for(node* i:tree->children){
    analyze(i);
  }
  tree->myDriver->exit();
}

void myParser(){
  if(!root)return;
#ifdef CHAPTER3
  root->display(0);
#endif
  analyze(root);
#ifdef CHAPTER5
  error2->display();
#endif
#ifdef CHAPTER7
  error2->display();
  oneIR->display();
#endif
}







